package com.chuangke.flow.controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.chuangke.common.db.page.CkPageQuery;
import com.chuangke.common.http.HttpResult;
import com.chuangke.common.utils.SecurityUtils;
import com.chuangke.flow.dao.FlowRuFlowDao;
import com.chuangke.flow.domain.FlowAuditResult;
import com.chuangke.flow.domain.FlowHandler;
import com.chuangke.flow.entity.FlowRuFlow;
import com.chuangke.flow.service.FlowQueryService;
import com.chuangke.flow.service.FlowTaskService;

/**
 * 【请填写功能名称】Controller
 * 
 * @author chuangke
 * @date "2020-09-27"
 */
@RestController
@RequestMapping("/flow")
public class FlowRuFlowController {

	@Autowired
	private FlowRuFlowDao flowRuFlowDao;

	@Autowired
	private FlowTaskService flowTaskService;

	@Autowired
	private FlowQueryService flowQueryService;

	/**
	 * 任务列表
	 * 
	 * @param businessKey
	 * @return
	 */
	@PreAuthorize("hasAuthority('login:action')")
	@GetMapping(value = "/tasklist/{businessKey}")
	public HttpResult taskList(@PathVariable String businessKey) {
		return HttpResult.ok(flowQueryService.listTask(businessKey));
	}

	/**
	 * 审批列表
	 * 
	 * @param businessKey
	 * @return
	 */
	@PreAuthorize("hasAuthority('login:action')")
	@GetMapping(value = "/approvallist/{businessKey}")
	public HttpResult taskApprovalList(@PathVariable String businessKey) {
		return HttpResult.ok(flowQueryService.listApprovalInfo(businessKey));
	}

	/**
	 * 批量审批，包含同意、退回
	 * 
	 * @return
	 */
	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping(value = "auditbatch")
	public HttpResult auditBatch(@RequestBody List<FlowHandler> handlers) {
//		return HttpResult.ok(flowTaskService.complete(handlers));
		Map<String, List<FlowHandler>> handlerCategoryMap = categoryHandler(handlers);

		FlowAuditResult result = new FlowAuditResult();
		result.setSuccessCount(0);
		result.setFailCount(0);
		result.setFailMsgList(new ArrayList<>());
		result.setSuccessMsgList(new ArrayList<>());
		result.setSuccessOrderIdList(new ArrayList<>());
		result.setFailOrderIdList(new ArrayList<>());
		for (List<FlowHandler> handlerList : handlerCategoryMap.values()) {
			for(FlowHandler fh : handlerList) {
				FlowAuditResult r1 = flowTaskService.complete(Arrays.asList(fh));
				result.setFailCount(result.getFailCount() + r1.getFailCount());
				result.setSuccessCount(result.getSuccessCount() + r1.getSuccessCount());
				result.getFailMsgList().addAll(r1.getFailMsgList());
				result.getSuccessMsgList().addAll(r1.getSuccessMsgList());
				result.getFailOrderIdList().addAll(r1.getFailOrderIdList());
				result.getSuccessOrderIdList().addAll(r1.getSuccessOrderIdList());
			}
		}
		return HttpResult.ok(result);
	}

	/**
	 * 批量撤回
	 * 
	 * @return
	 */
	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping(value = "revokebatch")
	public HttpResult revokeBatch(@RequestBody List<FlowHandler> handlers) {
		Map<String, List<FlowHandler>> handlerCategoryMap = categoryHandler(handlers);

		FlowAuditResult result = new FlowAuditResult();
		result.setSuccessCount(0);
		result.setFailCount(0);
		result.setFailMsgList(new ArrayList<>());
		result.setSuccessMsgList(new ArrayList<>());
		result.setSuccessOrderIdList(new ArrayList<>());
		result.setFailOrderIdList(new ArrayList<>());
		for (List<FlowHandler> handlerList : handlerCategoryMap.values()) {
			for(FlowHandler fh : handlerList) {
				FlowAuditResult r1 = flowTaskService.revoke(Arrays.asList(fh));
				result.setFailCount(result.getFailCount() + r1.getFailCount());
				result.setSuccessCount(result.getSuccessCount() + r1.getSuccessCount());
				result.getFailMsgList().addAll(r1.getFailMsgList());
				result.getSuccessMsgList().addAll(r1.getSuccessMsgList());
				result.getFailOrderIdList().addAll(r1.getFailOrderIdList());
				result.getSuccessOrderIdList().addAll(r1.getSuccessOrderIdList());
			}
		}

		return HttpResult.ok(result);
	}

	private Map<String, List<FlowHandler>> categoryHandler(List<FlowHandler> handlers) {
		if (CollectionUtils.isEmpty(handlers)) {
			return new HashMap<>();
		}

		List<String> orderIds = handlers.stream().map(FlowHandler::getBusinessKey).collect(Collectors.toList());
		QueryWrapper<FlowRuFlow> qw = new QueryWrapper<>();
		qw.lambda().in(FlowRuFlow::getOrderId, orderIds);
		List<FlowRuFlow> flowList = flowRuFlowDao.list(qw);
		if (CollectionUtils.isEmpty(flowList)) {
			return new HashMap<>();
		}

		Map<String, FlowHandler> handleMap = handlers.stream()
				.collect(Collectors.toMap(FlowHandler::getBusinessKey, a -> a));
		Map<String, List<FlowRuFlow>> flowMap = flowList.stream()
				.collect(Collectors.groupingBy(FlowRuFlow::getOrderType));

		Map<String, List<FlowHandler>> handlerCategoryMap = new HashMap<>();

		for (Map.Entry<String, List<FlowRuFlow>> entry : flowMap.entrySet()) {
			handlerCategoryMap.put(entry.getKey(),
					entry.getValue().stream().map(f -> handleMap.get(f.getOrderId())).collect(Collectors.toList()));
		}

		return handlerCategoryMap;
	}

	/**
	 * 我的待办
	 * 
	 * @param pageQuery
	 * @return
	 */
	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping(value = "/todo")
	public HttpResult todoTask(@RequestBody Map<String, Object> pageQuery) {
		String userId = SecurityUtils.getUserId();
		pageQuery.put("userId", userId);
		return HttpResult.ok(flowQueryService.findTodoTask(new CkPageQuery(pageQuery)));
	}
	/**
	 * 我的待办（带名称）
	 *
	 * @param pageQuery
	 * @return
	 */
	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping(value = "/todoAndName")
	public HttpResult findTodoForName(@RequestBody Map<String, Object> pageQuery) {
		String userId = SecurityUtils.getUserId();
		pageQuery.put("userId", userId);
		return HttpResult.ok(flowQueryService.findTodoForName(new CkPageQuery(pageQuery)));
	}

	@GetMapping(value = "/todocount")
	public HttpResult todoTaskCount() {
		String userId = SecurityUtils.getUserId();
		return HttpResult.ok(flowQueryService.findTodoTaskCount(userId));
	}

	@PostMapping(value = "/todocount2")
	public HttpResult todoTaskCount2(@RequestBody HashMap<String, Object> pageQuery) {
		String userId = SecurityUtils.getUserId();
		pageQuery.put("userId", userId);
		return HttpResult.ok(flowQueryService.findTodoTaskCount2(pageQuery));
	}

	/**
	 * 获取已办列表
	 */
	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping(value = "/done")
	public HttpResult doneTask(@RequestBody Map<String, Object> pageQuery) {
		String userId = SecurityUtils.getUserId();
		pageQuery.put("userId", userId);
		return HttpResult.ok(flowQueryService.findDoneTask(new CkPageQuery(pageQuery)));
	}
	/**
	 * 获取已办列表
	 */
	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping(value = "/doneWithName")
	public HttpResult doneTaskWithName(@RequestBody Map<String, Object> pageQuery) {
		String userId = SecurityUtils.getUserId();
		pageQuery.put("userId", userId);
		return HttpResult.ok(flowQueryService.findDoneTaskWithName(new CkPageQuery(pageQuery)));
	}

	@GetMapping(value = "/donecount")
	public HttpResult doneTaskCount() {
		String userId = SecurityUtils.getUserId();
		return HttpResult.ok(flowQueryService.findDoneTaskCount(userId));
	}

	/**
	 * 获取已办结列表
	 */
	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping(value = "/doneandover")
	public HttpResult doneAndOverTask(@RequestBody Map<String, Object> pageQuery) {
		String userId = SecurityUtils.getUserId();
		pageQuery.put("userId", userId);
		return HttpResult.ok(flowQueryService.findDownAndOverTask(new CkPageQuery(pageQuery)));
	}
	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping(value = "/doneandoverWithName")
	public HttpResult doneAndOverTaskWithName(@RequestBody Map<String, Object> pageQuery) {
		String userId = SecurityUtils.getUserId();
		pageQuery.put("userId", userId);
		return HttpResult.ok(flowQueryService.findDownAndOverTaskWithName(new CkPageQuery(pageQuery)));
	}

	/**
	 * 获取已办结数量
	 */
	@GetMapping(value = "/doneandovercount")
	public HttpResult doneAndOverTaskCount() {
		String userId = SecurityUtils.getUserId();
		return HttpResult.ok(flowQueryService.findDownAndOverTaskCount(userId));
	}

	/**
	 * 获取我的单据列表
	 */
	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping(value = "/mycreated")
	public HttpResult myCreatedTask(@RequestBody Map<String, Object> pageQuery) {
		String userId = SecurityUtils.getUserId();
		pageQuery.put("userId", userId);
		return HttpResult.ok(flowQueryService.findMyCreatedTask(new CkPageQuery(pageQuery)));
	}
	/**
	 * 获取我的单据列表(含任务名称)
	 */
	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping(value = "/mycreatedWithName")
	public HttpResult myCreatedTaskForName(@RequestBody Map<String, Object> pageQuery) {
		String userId = SecurityUtils.getUserId();
		pageQuery.put("userId", userId);
		return HttpResult.ok(flowQueryService.findMyCreatedTaskForName(new CkPageQuery(pageQuery)));
	}

	/**
	 * 获取我的单据数量
	 */
	@GetMapping(value = "/mycreatedcount")
	public HttpResult myCreatedTaskCount() {
		String userId = SecurityUtils.getUserId();
		return HttpResult.ok(flowQueryService.findMyCreatedTaskCount(userId));
	}

	/**
	 * 获取我的退回单据
	 */
	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping(value = "/myreject")
	public HttpResult myRejectTask(@RequestBody Map<String, Object> pageQuery) {
		String userId = SecurityUtils.getUserId();
		pageQuery.put("userId", userId);
		return HttpResult.ok(flowQueryService.findRejectTask(new CkPageQuery(pageQuery)));
	}
	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping(value = "/myrejectWithName")
	public HttpResult myRejectTaskWithName(@RequestBody Map<String, Object> pageQuery) {
		String userId = SecurityUtils.getUserId();
		pageQuery.put("userId", userId);
		return HttpResult.ok(flowQueryService.findRejectTaskWithName(new CkPageQuery(pageQuery)));
	}

	/**
	 * 获取我的退回单据数量
	 */
	@GetMapping(value = "/myrejectcount")
	public HttpResult myRejectTaskCount() {
		String userId = SecurityUtils.getUserId();
		return HttpResult.ok(flowQueryService.findRejectTaskCount(userId));
	}
	
	/**
	 * 获取下一个审批人
	 */
	@PreAuthorize("hasAuthority('login:action')")
	@PostMapping(value = "/nextApprovers")
	public HttpResult listNextAuditUsers(@RequestBody Map<String, Object> pageQuery) {
		String orderId = (String)pageQuery.get("orderId") ;
		String userId = SecurityUtils.getUserId();
		return HttpResult.ok(flowQueryService.listNextAuditUsers(orderId,userId));
	}
}
